﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CoreUtils.WIL
{
    /// <summary>
    /// Arithmetic functions from WIL library
    /// </summary>
    public class Arithmetic
    {
        public static FVIL.Data.CFviImage addOperation(FVIL.Data.CFviImage src1, FVIL.Data.CFviImage src2)
        {
            FVIL.Operation.CFviAddOperation parser = new FVIL.Operation.CFviAddOperation();
            FVIL.Data.CFviImage dst = new FVIL.Data.CFviImage();
            int valid = FVIL.Operation.CFviAddOperation.CheckValidity(src1, src2);
            if (valid != FVIL.ErrorCode._SUCCESS)
                throw new FVIL.CFviException(valid, "FVIL.Operation.CFviAddOperation.CheckValidity");
            parser.SrcImages[0] = src1;
            parser.SrcImages[1] = src2;
            parser.DstImages[0] = dst;
            if (!parser.IsValid())
                parser.Validate();
            parser.Execute();
            return dst;
        }

        public static FVIL.Data.CFviImage addScalar(FVIL.Data.CFviImage src, double value)
        {
            FVIL.Operation.CFviAddScalar parser = new FVIL.Operation.CFviAddScalar();
            FVIL.Data.CFviImage dst = new FVIL.Data.CFviImage();
            int valid = FVIL.Operation.CFviAddScalar.CheckValidity(src);
            if (valid != FVIL.ErrorCode._SUCCESS)
                throw new FVIL.CFviException(valid, "FVIL.Operation.CFviAddScalar.CheckValidity");
            parser.SrcImages[0] = src;
            parser.DstImages[0] = dst;
            if (!parser.IsValid())
                parser.Validate();
            parser.Value = value;
            parser.Execute();
            return dst;
        }

        public static FVIL.Data.CFviImage subOperation(FVIL.Data.CFviImage src1, FVIL.Data.CFviImage src2)
        {
            FVIL.Operation.CFviSubOperation parser = new FVIL.Operation.CFviSubOperation();
            FVIL.Data.CFviImage dst = new FVIL.Data.CFviImage();
            int valid = FVIL.Operation.CFviSubOperation.CheckValidity(src1, src2);
            if (valid != FVIL.ErrorCode._SUCCESS)
                throw new FVIL.CFviException(valid, "FVIL.Operation.CFviSubOperation.CheckValidity");
            parser.SrcImages[0] = src1;
            parser.SrcImages[1] = src2;
            parser.DstImages[0] = dst;
            if (!parser.IsValid())
                parser.Validate();
            parser.Execute();
            return dst;
        }

        public static FVIL.Data.CFviImage subScalar(FVIL.Data.CFviImage src, double value)
        {
            FVIL.Operation.CFviSubScalar parser = new FVIL.Operation.CFviSubScalar();
            FVIL.Data.CFviImage dst = new FVIL.Data.CFviImage();
            int valid = FVIL.Operation.CFviSubScalar.CheckValidity(src);
            if (valid != FVIL.ErrorCode._SUCCESS)
                throw new FVIL.CFviException(valid, "FVIL.Operation.CFviSubScalar.CheckValidity");
            parser.SrcImages[0] = src;
            parser.DstImages[0] = dst;
            if (!parser.IsValid())
                parser.Validate();
            parser.SwapOrder = false;
            parser.Value = value;
            parser.Execute();
            return dst;
        }

        public static FVIL.Data.CFviImage mulOperation(FVIL.Data.CFviImage src1, FVIL.Data.CFviImage src2)
        {
            FVIL.Operation.CFviMulOperation parser = new FVIL.Operation.CFviMulOperation();
            FVIL.Data.CFviImage dst = new FVIL.Data.CFviImage();
            int valid = FVIL.Operation.CFviMulOperation.CheckValidity(src1, src2);
            if (valid != FVIL.ErrorCode._SUCCESS)
                throw new FVIL.CFviException(valid, "FVIL.Operation.CFviMulOperation.CheckValidity");
            parser.SrcImages[0] = src1;
            parser.SrcImages[1] = src2;
            parser.DstImages[0] = dst;
            if (!parser.IsValid())
                parser.Validate();
            parser.Execute();
            return dst;
        }

        public static FVIL.Data.CFviImage mulScalar(FVIL.Data.CFviImage src, double value)
        {
            FVIL.Operation.CFviMulScalar parser = new FVIL.Operation.CFviMulScalar();
            FVIL.Data.CFviImage dst = new FVIL.Data.CFviImage();
            int valid = FVIL.Operation.CFviMulScalar.CheckValidity(src);
            if (valid != FVIL.ErrorCode._SUCCESS)
                throw new FVIL.CFviException(valid, "FVIL.Operation.CFviMulScalar.CheckValidity");
            parser.SrcImages[0] = src;
            parser.DstImages[0] = dst;
            if (!parser.IsValid())
                parser.Validate();
            parser.Value = value;
            parser.Execute();
            return dst;
        }

        public static FVIL.Data.CFviImage divOperation(FVIL.Data.CFviImage src1, FVIL.Data.CFviImage src2)
        {
            FVIL.Operation.CFviDivOperation parser = new FVIL.Operation.CFviDivOperation();
            FVIL.Data.CFviImage dst = new FVIL.Data.CFviImage();
            int valid = FVIL.Operation.CFviDivOperation.CheckValidity(src1, src2);
            if (valid != FVIL.ErrorCode._SUCCESS)
                throw new FVIL.CFviException(valid, "FVIL.Operation.CFviDivOperation.CheckValidity");
            parser.SrcImages[0] = src1;
            parser.SrcImages[1] = src2;
            parser.DstImages[0] = dst;
            if (!parser.IsValid())
                parser.Validate();
            for (int ch = 0; ch < src2.Channel; ch++)
            {
                try
                {
                    FVIL.Data.CFviPoint _pos = new FVIL.Data.CFviPoint();
                    System.Drawing.Color _rgb = System.Drawing.Color.FromArgb(0x00, 0x00, 0x00, 0x00);
                    switch (src2.ImageType)
                    {
                        case FVIL.ImageType.RGB24:
                        case FVIL.ImageType.RGB32:
                            _pos = src2.FindRGB(ch, _rgb, 0.0, 0);
                            break;
                        default:
                            _pos = src2.Find(ch, 0.0, 0.0, 0);
                            break;
                    }
                    //return;
                }
                catch (FVIL.CFviException)
                {
                    // not found
                }
            }
            parser.Execute();
            return dst;
        }

        public static FVIL.Data.CFviImage divScalar(FVIL.Data.CFviImage src, double value)
        {
            FVIL.Operation.CFviDivScalar parser = new FVIL.Operation.CFviDivScalar();
            FVIL.Data.CFviImage dst = new FVIL.Data.CFviImage();
            int valid = FVIL.Operation.CFviDivScalar.CheckValidity(src);
            if (valid != FVIL.ErrorCode._SUCCESS)
                throw new FVIL.CFviException(valid, "FVIL.Operation.CFviDivScalar.CheckValidity");
            parser.SrcImages[0] = src;
            parser.DstImages[0] = dst;
            if (!parser.IsValid())
                parser.Validate();
            parser.SwapOrder = false;
            parser.Value = value;
            parser.Execute();
            return dst;
        }

        public static FVIL.Data.CFviImage diffOperation(FVIL.Data.CFviImage src1, FVIL.Data.CFviImage src2)
        {
            FVIL.Operation.CFviDiffOperation parser = new FVIL.Operation.CFviDiffOperation();
            FVIL.Data.CFviImage dst = new FVIL.Data.CFviImage();
            int valid = FVIL.Operation.CFviDiffOperation.CheckValidity(src1, src2);
            if (valid != FVIL.ErrorCode._SUCCESS)
                throw new FVIL.CFviException(valid, "FVIL.Operation.CFviDiffOperation.CheckValidity");
            parser.SrcImages[0] = src1;
            parser.SrcImages[1] = src2;
            parser.DstImages[0] = dst;
            if (!parser.IsValid())
                parser.Validate();
            parser.Execute();
            return dst;
        }

        public static FVIL.Data.CFviImage diffScalar(FVIL.Data.CFviImage src, double value)
        {
            FVIL.Operation.CFviDiffScalar parser = new FVIL.Operation.CFviDiffScalar();
            FVIL.Data.CFviImage dst = new FVIL.Data.CFviImage();
            int valid = FVIL.Operation.CFviDiffScalar.CheckValidity(src);
            if (valid != FVIL.ErrorCode._SUCCESS)
                throw new FVIL.CFviException(valid, "FVIL.Operation.CFviDiffScalar.CheckValidity");
            parser.SrcImages[0] = src;
            parser.DstImages[0] = dst;
            if (!parser.IsValid())
                parser.Validate();
            parser.Value = value;
            parser.Execute();
            return dst;
        }

        public static FVIL.Data.CFviImage minOperation(FVIL.Data.CFviImage src1, FVIL.Data.CFviImage src2)
        {
            FVIL.Operation.CFviMinOperation parser = new FVIL.Operation.CFviMinOperation();
            FVIL.Data.CFviImage dst = new FVIL.Data.CFviImage();
            int valid = FVIL.Operation.CFviMinOperation.CheckValidity(src1, src2);
            if (valid != FVIL.ErrorCode._SUCCESS)
                throw new FVIL.CFviException(valid, "FVIL.Operation.CFviMinOperation.CheckValidity");
            parser.SrcImages[0] = src1;
            parser.SrcImages[1] = src2;
            parser.DstImages[0] = dst;
            if (!parser.IsValid())
                parser.Validate();
            parser.Execute();
            return dst;
        }

        public static FVIL.Data.CFviImage minScalar(FVIL.Data.CFviImage src, double value)
        {
            FVIL.Operation.CFviMinScalar parser = new FVIL.Operation.CFviMinScalar();
            FVIL.Data.CFviImage dst = new FVIL.Data.CFviImage();
            int valid = FVIL.Operation.CFviMinScalar.CheckValidity(src);
            if (valid != FVIL.ErrorCode._SUCCESS)
                throw new FVIL.CFviException(valid, "FVIL.Operation.CFviMinScalar.CheckValidity");
            parser.SrcImages[0] = src;
            parser.DstImages[0] = dst;
            if (!parser.IsValid())
                parser.Validate();
            parser.Value = value;
            parser.Execute();
            return dst;
        }

        public static FVIL.Data.CFviImage maxOperation(FVIL.Data.CFviImage src1, FVIL.Data.CFviImage src2)
        {
            FVIL.Operation.CFviMaxOperation parser = new FVIL.Operation.CFviMaxOperation();
            FVIL.Data.CFviImage dst = new FVIL.Data.CFviImage();
            int valid = FVIL.Operation.CFviMaxOperation.CheckValidity(src1, src2);
            if (valid != FVIL.ErrorCode._SUCCESS)
                throw new FVIL.CFviException(valid, "FVIL.Operation.CFviMaxOperation.CheckValidity");
            parser.SrcImages[0] = src1;
            parser.SrcImages[1] = src2;
            parser.DstImages[0] = dst;
            if (!parser.IsValid())
                parser.Validate();
            parser.Execute();
            return dst;
        }

        public static FVIL.Data.CFviImage maxScalar(FVIL.Data.CFviImage src, double value)
        {
            FVIL.Operation.CFviMaxScalar parser = new FVIL.Operation.CFviMaxScalar();
            FVIL.Data.CFviImage dst = new FVIL.Data.CFviImage();
            int valid = FVIL.Operation.CFviMaxScalar.CheckValidity(src);
            if (valid != FVIL.ErrorCode._SUCCESS)
                throw new FVIL.CFviException(valid, "FVIL.Operation.CFviMaxScalar.CheckValidity");
            parser.SrcImages[0] = src;
            parser.DstImages[0] = dst;
            if (!parser.IsValid())
                parser.Validate();
            parser.Value = value;
            parser.Execute();
            return dst;
        }

        public static FVIL.Data.CFviImage shiftOperation(FVIL.Data.CFviImage src, int shiftAmount)
        {
            FVIL.Operation.CFviShiftOperation parser = new FVIL.Operation.CFviShiftOperation();
            FVIL.Data.CFviImage dst = new FVIL.Data.CFviImage();
            int valid = FVIL.Operation.CFviShiftOperation.CheckValidity(src);
            if (valid != FVIL.ErrorCode._SUCCESS)
                throw new FVIL.CFviException(valid, "FVIL.Operation.CFviShiftOperation.CheckValidity");
            parser.SrcImages[0] = src;
            parser.DstImages[0] = dst;
            if (!parser.IsValid())
                parser.Validate();
            parser.ShiftAmount = shiftAmount;
            parser.Execute();
            return dst;
        }

        public static FVIL.Data.CFviImage maskOperation(FVIL.Data.CFviImage src1, FVIL.Data.CFviImage src2)
        {
            FVIL.Operation.CFviMaskOperation parser = new FVIL.Operation.CFviMaskOperation();
            FVIL.Data.CFviImage dst = new FVIL.Data.CFviImage();
            int valid = FVIL.Operation.CFviMaskOperation.CheckValidity(src1, src2);
            if (valid != FVIL.ErrorCode._SUCCESS)
                throw new FVIL.CFviException(valid, "FVIL.Operation.CFviMaskOperation.CheckValidity");
            parser.SrcImages[0] = src1;
            parser.SrcImages[1] = src2;
            parser.DstImages[0] = dst;
            if (!parser.IsValid())
                parser.Validate();
            parser.Execute();
            return dst;
        }
    }
}
